package pneuservis.frontend.web;

import java.util.List;
import javax.ejb.EJB;
import net.sourceforge.stripes.action.ActionBean;
import net.sourceforge.stripes.action.ActionBeanContext;
import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.action.SessionScope;
import net.sourceforge.stripes.action.UrlBinding;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidateNestedProperties;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.util.Factory;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pneuservis.backend.entities.Customer;
import pneuservis.backend.to.CustomerTO;
import net.sourceforge.stripes.validation.ValidateNestedProperties;
import pneuservis.backend.services.CustomerServiceLocal;

/**
 *
 * @author martin
 */
@UrlBinding("/login/{$event}")
@SessionScope
public class SecurityActionBean implements ActionBean {

    private ActionBeanContext context;
    private static Factory<SecurityManager> shiroFactory = null;

    public SecurityActionBean() {
        if (shiroFactory != null) {
            log.info("SecurityActionBean");
            Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
            SecurityManager securityManager = factory.getInstance();
            SecurityUtils.setSecurityManager(securityManager);
        }


    }
    final static Logger log = LoggerFactory.getLogger(SecurityActionBean.class);
    @EJB(lookup = "java:global/cz.muni.fi.pa165.pneuservis_Pneuservis-ear_ear_1.0-SNAPSHOT/Pneuservis-ejb-1.0-SNAPSHOT/CustomerService")
    private CustomerServiceLocal customerService;
//    
//    @ValidateNestedProperties(value = {
//        @Validate(on = {"save"}, field = "username", required = true),
//        @Validate(on = {"save"}, field = "password", required = true),})
    private String username;
    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    private boolean login(String username, String password) {

        //log.error("==============logging: " + username + " password:" + password+"===========================");

        Subject currentUser = SecurityUtils.getSubject();
        


        if (!currentUser.isAuthenticated()) {
            try {
                currentUser.login(new UsernamePasswordToken(username, password));

                if (!currentUser.hasRole("admin")) {
                    Session session = currentUser.getSession();
                    List<CustomerTO> customers = customerService.findCustomerByName(username);//TODO fix findCustomerByName tak aby vraciala presne jedneho zakaznika alebo null tak aby som sa tu nemusel srat s kolekciou a mohol pridelit spravne session 


                    if (customers.isEmpty()) {//TODO tu bude customer == null, (bude to znamenat ze sa pravdepodobne hlasi admin)
                        log.error("Valid username and password does not have customer account! username[" + username + "] password[" + password + "]");
                        return false;
                    }
                    session.setAttribute(username, customers.get(0).getId());
                }
                //if no exception, that's it, we're done!
            } catch (UnknownAccountException uae) {
                return false;
            } catch (IncorrectCredentialsException ice) {
                return false;
            } catch (LockedAccountException lae) {
                return false;
            } catch (AuthenticationException ae) {
                return false;
            }
        }
        return true;
    }

    public Resolution login() {
        if (!login(username, password)) {
            // invalid login
            return new ForwardResolution("/index.jsp");
        }
        if (SecurityUtils.getSubject().hasRole("user")) {
            //TODO find out better site to redirect
            return new ForwardResolution("/customerLogged.jsp");
        }
        if (SecurityUtils.getSubject().hasRole("admin")) {
            //TODO find out better site to redirect
            return new ForwardResolution("/showService.jsp");
        }
        log.error("unexpected user without role has logged sucessfuly o_O username[" + username + "] password[" + password + "]");
        return new ForwardResolution("/index.jsp");
    }

    public Resolution logout() {
        SecurityUtils.getSubject().logout();
        return new ForwardResolution("/index.jsp");
    }

    public void createUser() {
    }

    public void createAdmin() {
    }

    public void removeUser() {
    }

    public void removeAdmin() {
    }

    @Override
    public ActionBeanContext getContext() {
        return context;
    }

    @Override
    public void setContext(ActionBeanContext context) {
        this.context = context;
    }

    @DefaultHandler
    public Resolution def() {
        return new ForwardResolution("/login_1.jsp");
    }
}